home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / gui / gtlayout.lha / Source / LTP_TextEditClass.c < prev    next >
C/C++ Source or Header  |  1999-01-03  |  18KB  |  919 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1999 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. /******************************************************************************/
  15.  
  16. #ifdef DO_TEXTEDIT_KIND    /* Support code */
  17.  
  18. /******************************************************************************/
  19.  
  20. #include <clib/keymap_protos.h>
  21. #include <clib/layers_protos.h>
  22. #include <clib/alib_protos.h>    /* For Coerce/Do/DoSuperMethod */
  23.  
  24. #include <pragmas/keymap_pragmas.h>
  25. #include <pragmas/layers_pragmas.h>
  26.  
  27. /******************************************************************************/
  28.  
  29. #define G(x) ((struct Gadget *)x)
  30.  
  31. /******************************************************************************/
  32.  
  33. #define CLEAR_FLAG(v,f)        ((v) &= (~(f)))
  34. #define SET_FLAG(v,f)        ((v) |=   (f))
  35. #define FLAG_IS_SET(v,f)    (((v) & (f)) != 0)
  36. #define FLAG_IS_CLEAR(v,f)    (((v) & (f)) == 0)
  37.  
  38. /******************************************************************************/
  39.  
  40. #define RAWKEY_BACKSPACE    65
  41. #define RAWKEY_TAB            66
  42. #define RAWKEY_ENTER        67
  43. #define RAWKEY_RETURN        68
  44. #define RAWKEY_HELP            95
  45.  
  46. /******************************************************************************/
  47.  
  48. #define IS_CONTROL_CHARACTER(c) ((c & 0xE0) == 0)
  49.  
  50. /******************************************************************************/
  51.  
  52. #define IEQUALIFIER_SHIFT    (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)
  53. #define IEQUALIFIER_ALT        (IEQUALIFIER_LALT|IEQUALIFIER_RALT)
  54.  
  55. /******************************************************************************/
  56.  
  57. STATIC VOID
  58. DrawButtonBevel(
  59.     struct RastPort *    rp,
  60.     UWORD *                pens,
  61.     BOOL                recessed,
  62.     LONG                left,
  63.     LONG                top,
  64.     LONG                width,
  65.     LONG                height)
  66. {
  67.     UWORD shinePen,shadowPen;
  68.  
  69.     if(recessed)
  70.     {
  71.         shinePen    = pens[SHADOWPEN];
  72.         shadowPen    = pens[SHINEPEN];
  73.     }
  74.     else
  75.     {
  76.         shinePen    = pens[SHINEPEN];
  77.         shadowPen    = pens[SHADOWPEN];
  78.     }
  79.  
  80.     SetDrMd(rp,JAM1);
  81.  
  82.     SetAPen(rp,shinePen);
  83.     Move(rp,left + width - 2,top);
  84.     Draw(rp,left,top);
  85.     Draw(rp,left,top + height - 1);
  86.     Move(rp,left + 1,top + height - 2);
  87.     Draw(rp,left + 1,top + 1);
  88.  
  89.     SetAPen(rp,shadowPen);
  90.     Move(rp,left + 1,top + height - 1);
  91.     Draw(rp,left + width - 1,top + height - 1);
  92.     Draw(rp,left + width - 1,top);
  93.     Move(rp,left + width - 2,top + 1);
  94.     Draw(rp,left + width - 2,top + height - 2);
  95. }
  96.  
  97. /******************************************************************************/
  98.  
  99. STATIC Object *
  100. NewMethod(
  101.     Class *            cl,
  102.     Object *        o,
  103.     struct opSet *    ops)
  104. {
  105.     Object * result;
  106.  
  107.     result = (Object *)DoSuperMethodA(cl,o,(Msg)ops);
  108.     if(result != NULL)
  109.     {
  110.         struct TextEditInfo * tei = INST_DATA(cl,result);
  111.         struct DrawInfo * dri;
  112.         BOOL success = FALSE;
  113.  
  114.         dri = (struct DrawInfo *)GetTagData(GA_DrawInfo,(ULONG)NULL,ops->ops_AttrList);
  115.         if(dri != NULL)
  116.         {
  117.             BOOL gotTheFrame;
  118.  
  119.             tei->tei_DrawInfo = dri;
  120.  
  121.             if(IntuitionBase->lib_Version < 39)
  122.             {
  123.                 gotTheFrame = TRUE;
  124.             }
  125.             else
  126.             {
  127.                 tei->tei_Frame = NewObject(NULL,FRAMEICLASS,
  128.                     IA_FrameType,    FRAME_RIDGE,
  129.                     IA_EdgesOnly,    TRUE,
  130.                 TAG_DONE);
  131.  
  132.                 gotTheFrame = (BOOL)(tei->tei_Frame != NULL);
  133.             }
  134.  
  135.             if(gotTheFrame)
  136.             {
  137.                 struct TextFont * font;
  138.                 struct IBox outBox;
  139.  
  140.                 if(tei->tei_Frame != NULL)
  141.                 {
  142.                     struct IBox inBox;
  143.                     struct impFrameBox frameBoxMsg;
  144.  
  145.                     frameBoxMsg.MethodID        = IM_FRAMEBOX;
  146.                     frameBoxMsg.imp_ContentsBox    = &inBox;
  147.                     frameBoxMsg.imp_FrameBox    = &outBox;
  148.                     frameBoxMsg.imp_DrInfo        = dri;
  149.                     frameBoxMsg.imp_FrameFlags    = 0;
  150.  
  151.                     memset(&inBox,0,sizeof(inBox));
  152.  
  153.                     DoMethodA((Object *)tei->tei_Frame,&frameBoxMsg);
  154.                 }
  155.                 else
  156.                 {
  157.                     outBox.Left    = -6;
  158.                     outBox.Top    = -3;
  159.                 }
  160.  
  161.                 tei->tei_FrameLeft    = (-outBox.Left);
  162.                 tei->tei_FrameTop    = (-outBox.Top);
  163.  
  164.                 font = (struct TextFont *)GetTagData(STRINGA_Font,(ULONG)NULL,ops->ops_AttrList);
  165.  
  166.                 tei->tei_Context = TE_CreateTextEditContext(dri,font);
  167.                 if(tei->tei_Context != NULL)
  168.                 {
  169.                     if(TE_SetTextEditString(tei->tei_Context,""))
  170.                     {
  171.                         tei->tei_Dragging        = FALSE;
  172.                         tei->tei_NoFilterMode    = TRUE;
  173.                         tei->tei_ExitHelp        = FALSE;
  174.  
  175.                         DoMethod(result,OM_SET,ops->ops_AttrList,NULL);
  176.  
  177.                         success = TRUE;
  178.                     }
  179.                 }
  180.             }
  181.         }
  182.  
  183.         if(NO success)
  184.         {
  185.             CoerceMethod(cl,result,OM_DISPOSE);
  186.             result = NULL;
  187.         }
  188.     }
  189.  
  190.     return(result);
  191. }
  192.  
  193. STATIC ULONG
  194. SetMethod(
  195.     Class *            cl,
  196.     Object *        o,
  197.     struct opSet *    ops)
  198. {
  199.     struct TextEditInfo * tei = INST_DATA(cl,o);
  200.     struct TextEditContext * tec = tei->tei_Context;
  201.     struct RastPort * rp;
  202.     struct TagItem * tag;
  203.     struct TagItem * list;
  204.     BOOL mustRefresh;
  205.     LONG redrawMode;
  206.     BOOL isDisabled;
  207.     ULONG result;
  208.  
  209.     isDisabled = (BOOL)FLAG_IS_SET(G(o)->Flags,GFLG_DISABLED);
  210.     redrawMode = GREDRAW_UPDATE;
  211.  
  212.     result = DoSuperMethodA(cl,o,(Msg)ops);
  213.     mustRefresh = result;
  214.  
  215.     list = ops->ops_AttrList;
  216.     while((tag = NextTagItem(&list)) != NULL)
  217.     {
  218.         BOOL setBox = FALSE;
  219.  
  220.         switch(tag->ti_Tag)
  221.         {
  222.             case GA_Disabled:
  223.  
  224.                 if(isDisabled != (BOOL)(tag->ti_Data != 0))
  225.                 {
  226.                     mustRefresh = TRUE;
  227.                     redrawMode = GREDRAW_REDRAW;
  228.                 }
  229.  
  230.                 result = TRUE;
  231.  
  232.                 break;
  233.  
  234.             case STRINGA_Buffer:
  235.  
  236.                 TE_SetTextEditString(tec,(STRPTR)tag->ti_Data);
  237.  
  238.                 mustRefresh = TRUE;
  239.                 redrawMode = GREDRAW_REDRAW;
  240.  
  241.                 result = TRUE;
  242.  
  243.                 break;
  244.  
  245.             case STRINGA_BufferPos:
  246.  
  247.                 rp = ObtainGIRPort(ops->ops_GInfo);
  248.                 if(rp != NULL)
  249.                 {
  250.                     TE_SetTextEditRastPort(tec,rp);
  251.  
  252.                     TE_SetTextEditStringPosition(tec,tag->ti_Data);
  253.  
  254.                     ReleaseGIRPort(rp);
  255.                     TE_SetTextEditRastPort(tec,NULL);
  256.                 }
  257.  
  258.                 result = TRUE;
  259.  
  260.                 break;
  261.  
  262.             case STRINGA_NoFilterMode:
  263.  
  264.                 tei->tei_NoFilterMode = tag->ti_Data;
  265.                 break;
  266.  
  267.             case STRINGA_ExitHelp:
  268.  
  269.                 tei->tei_ExitHelp = tag->ti_Data;
  270.                 break;
  271.  
  272.             case STRINGA_AltKeyMap:
  273.  
  274.                 tei->tei_AltKeyMap = (struct KeyMap *)tag->ti_Data;
  275.                 break;
  276.  
  277.             case GA_Left:
  278.             case GA_Top:
  279.             case GA_Width:
  280.             case GA_Height:
  281.  
  282.                 setBox = TRUE;
  283.                 break;
  284.         }
  285.  
  286.         if(setBox)
  287.         {
  288.             struct impFrameBox frameBoxMsg;
  289.             struct IBox box;
  290.  
  291.             box = (*((struct IBox *)&G(o)->LeftEdge));
  292.  
  293.             box.Left    += tei->tei_FrameLeft;
  294.             box.Top        += tei->tei_FrameTop;
  295.             box.Width    -= 2 * tei->tei_FrameLeft;
  296.             box.Height    -= 2 * tei->tei_FrameTop;
  297.  
  298.             TE_SetTextEditBox(tec,&box);
  299.             mustRefresh = TRUE;
  300.  
  301.             if(tei->tei_Frame != NULL)
  302.             {
  303.                 box.Left    = tei->tei_FrameLeft;
  304.                 box.Top        = tei->tei_FrameTop;
  305.  
  306.                 frameBoxMsg.MethodID        = IM_FRAMEBOX;
  307.                 frameBoxMsg.imp_ContentsBox    = &box;
  308.                 frameBoxMsg.imp_FrameBox    = (struct IBox *)tei->tei_Frame;
  309.                 frameBoxMsg.imp_DrInfo        = tei->tei_DrawInfo;
  310.                 frameBoxMsg.imp_FrameFlags    = 0;
  311.  
  312.                 DoMethodA((Object *)tei->tei_Frame,&frameBoxMsg);
  313.             }
  314.         }
  315.     }
  316.  
  317.     if(mustRefresh)
  318.     {
  319.         rp = ObtainGIRPort(ops->ops_GInfo);
  320.         if(rp != NULL)
  321.         {
  322.             DoMethod(o,GM_RENDER,ops->ops_GInfo,rp,redrawMode);
  323.  
  324.             ReleaseGIRPort(rp);
  325.         }
  326.     }
  327.  
  328.     return(result);
  329. }
  330.  
  331. STATIC ULONG
  332. GetMethod(
  333.     Class *            cl,
  334.     Object *        o,
  335.     struct opGet *    opg)
  336. {
  337.     struct TextEditInfo * tei = INST_DATA(cl,o);
  338.     struct TextEditContext * tec = tei->tei_Context;
  339.     STRPTR string;
  340.     LONG value;
  341.     ULONG result;
  342.  
  343.     switch(opg->opg_AttrID)
  344.     {
  345.         case STRINGA_Buffer:
  346.  
  347.             TE_GetTextEditString(tec,&string);
  348.             (*opg->opg_Storage) = (ULONG)string;
  349.             result = TRUE;
  350.             break;
  351.  
  352.         case STRINGA_BufferPos:
  353.  
  354.             TE_GetTextEditStringPosition(tec,&value);
  355.             (*opg->opg_Storage) = (ULONG)value;
  356.             result = TRUE;
  357.             break;
  358.  
  359.         case STRINGA_NoFilterMode:
  360.  
  361.             (*opg->opg_Storage) = (ULONG)tei->tei_NoFilterMode;
  362.             result = TRUE;
  363.             break;
  364.  
  365.         case STRINGA_ExitHelp:
  366.  
  367.             (*opg->opg_Storage) = (ULONG)tei->tei_ExitHelp;
  368.             result = TRUE;
  369.             break;
  370.  
  371.         case STRINGA_AltKeyMap:
  372.  
  373.             (*opg->opg_Storage) = (ULONG)tei->tei_AltKeyMap;
  374.             result = TRUE;
  375.             break;
  376.  
  377.         default:
  378.  
  379.             result = DoSuperMethodA(cl,o,(Msg)opg);
  380.             break;
  381.     }
  382.  
  383.     return(result);
  384. }
  385.  
  386. STATIC ULONG
  387. RenderMethod(
  388.     Class *                cl,
  389.     Object *            o,
  390.     struct gpRender *    gpr)
  391. {
  392.     struct TextEditInfo * tei = INST_DATA(cl,o);
  393.     struct TextEditContext * tec = tei->tei_Context;
  394.     struct RastPort * rp = gpr->gpr_RPort;
  395.  
  396.     TE_SetTextEditRastPort(tec,rp);
  397.  
  398.     if(gpr->gpr_Redraw == GREDRAW_TOGGLE)
  399.     {
  400.         if(FLAG_IS_SET(G(o)->Flags,GFLG_SELECTED))
  401.             TE_Activate(tec);
  402.         else
  403.             TE_Deactivate(tec);
  404.     }
  405.     else
  406.     {
  407.         if(tei->tei_Frame != NULL)
  408.         {
  409.             DrawImageState(rp,(struct Image *)tei->tei_Frame,G(o)->LeftEdge,G(o)->TopEdge,IDS_NORMAL,tei->tei_DrawInfo);
  410.         }
  411.         else
  412.         {
  413.             DrawButtonBevel(rp,tei->tei_DrawInfo->dri_Pens,FALSE,G(o)->LeftEdge,G(o)->TopEdge,G(o)->Width,G(o)->Height);
  414.             DrawButtonBevel(rp,tei->tei_DrawInfo->dri_Pens,TRUE, G(o)->LeftEdge + 2,G(o)->TopEdge + 1,G(o)->Width - 4,G(o)->Height - 2);
  415.         }
  416.  
  417.         if(gpr->gpr_Redraw == GREDRAW_UPDATE)
  418.             TE_RedrawIfNecessary(tec);
  419.         else
  420.             TE_Refresh(tec);
  421.     }
  422.  
  423.     if(FLAG_IS_SET(G(o)->Flags,GFLG_DISABLED))
  424.         TE_DrawDisabled(tec);
  425.  
  426.     TE_SetTextEditRastPort(tec,NULL);
  427.  
  428.     return(TRUE);
  429. }
  430.  
  431. STATIC ULONG
  432. HitTestMethod(
  433.     Class *                cl,
  434.     Object *            o,
  435.     struct gpHitTest *    gpht)
  436. {
  437.     struct TextEditInfo * tei = INST_DATA(cl,o);
  438.     struct TextEditContext * tec = tei->tei_Context;
  439.     ULONG result = 0;
  440.  
  441.     if(FLAG_IS_CLEAR(G(o)->Flags,GFLG_DISABLED))
  442.     {
  443.         if(TE_MouseInArea(tec,gpht->gpht_Mouse.X,gpht->gpht_Mouse.Y))
  444.             result = GMR_GADGETHIT;
  445.     }
  446.  
  447.     return(result);
  448. }
  449.  
  450. STATIC ULONG
  451. InactiveMethod(
  452.     Class *                    cl,
  453.     Object *                o,
  454.     struct gpGoInactive *    gpgi)
  455. {
  456.     struct TextEditInfo * tei = INST_DATA(cl,o);
  457.     struct RastPort * rp;
  458.  
  459.     rp = ObtainGIRPort(gpgi->gpgi_GInfo);
  460.     if(rp != NULL)
  461.     {
  462.         CLEAR_FLAG(G(o)->Flags,GFLG_SELECTED);
  463.         DoMethod(o,GM_RENDER,gpgi->gpgi_GInfo,rp,GREDRAW_TOGGLE);
  464.  
  465.         ReleaseGIRPort(rp);
  466.     }
  467.  
  468.     tei->tei_Dragging = FALSE;
  469.  
  470.     return(0);
  471. }
  472.  
  473. STATIC ULONG
  474. ActiveMethod(
  475.     Class *                cl,
  476.     Object *            o,
  477.     struct gpInput *    gpi)
  478. {
  479.     struct RastPort * rp;
  480.     ULONG result;
  481.  
  482.     rp = ObtainGIRPort(gpi->gpi_GInfo);
  483.     if(rp != NULL)
  484.     {
  485.         struct TextEditInfo * tei = INST_DATA(cl,o);
  486.         struct TextEditContext * tec = tei->tei_Context;
  487.  
  488.         SET_FLAG(G(o)->Flags,GFLG_SELECTED);
  489.         DoMethod(o,GM_RENDER,gpi->gpi_GInfo,rp,GREDRAW_TOGGLE);
  490.  
  491.         if(gpi->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  492.         {
  493.             LONG x,y;
  494.  
  495.             TE_SetTextEditRastPort(tec,rp);
  496.  
  497.             x = gpi->gpi_Mouse.X - tei->tei_FrameLeft;
  498.             y = gpi->gpi_Mouse.Y - tei->tei_FrameTop;
  499.  
  500.             TE_CursorToMouse(tec,x,y);
  501.             tei->tei_Dragging = TRUE;
  502.  
  503.             TE_SetTextEditRastPort(tec,NULL);
  504.         }
  505.  
  506.         ReleaseGIRPort(rp);
  507.  
  508.         result = GMR_MEACTIVE;
  509.     }
  510.     else
  511.     {
  512.         result = GMR_NOREUSE;
  513.     }
  514.  
  515.     return(result);
  516. }
  517.  
  518. STATIC ULONG
  519. InputMethod(
  520.     Class *                cl,
  521.     Object *            o,
  522.     struct gpInput *    gpi)
  523. {
  524.     struct TextEditInfo * tei = INST_DATA(cl,o);
  525.     struct TextEditContext * tec = tei->tei_Context;
  526.     ULONG result = GMR_MEACTIVE;
  527.  
  528.     if(gpi->gpi_IEvent->ie_Class == IECLASS_TIMER)
  529.     {
  530.         if(tei->tei_Dragging)
  531.         {
  532.             struct RastPort * rp = ObtainGIRPort(gpi->gpi_GInfo);
  533.             if(rp != NULL)
  534.             {
  535.                 LONG x,y;
  536.  
  537.                 TE_SetTextEditRastPort(tec,rp);
  538.  
  539.                 x = gpi->gpi_Mouse.X - tei->tei_FrameLeft;
  540.                 y = gpi->gpi_Mouse.Y - tei->tei_FrameTop;
  541.  
  542.                 TE_MoveCursorWithMouse(tec,x,y);
  543.  
  544.                 TE_SetTextEditRastPort(tec,NULL);
  545.                 ReleaseGIRPort(rp);
  546.             }
  547.         }
  548.     }
  549.     else if (gpi->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  550.     {
  551.         switch(gpi->gpi_IEvent->ie_Code)
  552.         {
  553.             case MENUDOWN:
  554.  
  555.                 result = GMR_REUSE;
  556.                 break;
  557.  
  558.             case SELECTDOWN:
  559.  
  560.                 if(NOT TE_MouseInArea(tec,gpi->gpi_Mouse.X,gpi->gpi_Mouse.Y))
  561.                 {
  562.                     result = GMR_REUSE;
  563.                 }
  564.                 else
  565.                 {
  566.                     struct RastPort * rp = ObtainGIRPort(gpi->gpi_GInfo);
  567.                     if(rp != NULL)
  568.                     {
  569.                         LONG x,y;
  570.  
  571.                         TE_SetTextEditRastPort(tec,rp);
  572.  
  573.                         x = gpi->gpi_Mouse.X - tei->tei_FrameLeft;
  574.                         y = gpi->gpi_Mouse.Y - tei->tei_FrameTop;
  575.  
  576.                         TE_CursorToMouse(tec,x,y);
  577.                         tei->tei_Dragging = TRUE;
  578.  
  579.                         TE_SetTextEditRastPort(tec,NULL);
  580.                         ReleaseGIRPort(rp);
  581.                     }
  582.                 }
  583.  
  584.                 break;
  585.  
  586.             case SELECTUP:
  587.  
  588.                 tei->tei_Dragging = FALSE;
  589.                 break;
  590.         }
  591.     }
  592.     else if (gpi->gpi_IEvent->ie_Class == IECLASS_RAWKEY)
  593.     {
  594.         if(FLAG_IS_CLEAR(gpi->gpi_IEvent->ie_Code,IECODE_UP_PREFIX))
  595.         {
  596.             struct RastPort * rp;
  597.  
  598.             rp = ObtainGIRPort(gpi->gpi_GInfo);
  599.             if(rp != NULL)
  600.             {
  601.                 ULONG qualifier = gpi->gpi_IEvent->ie_Qualifier;
  602.                 UWORD code = gpi->gpi_IEvent->ie_Code;
  603.                 UBYTE c;
  604.  
  605.                 TE_SetTextEditRastPort(tec,rp);
  606.  
  607.                 if(MapRawKey(gpi->gpi_IEvent,&c,1,tei->tei_AltKeyMap) == 1)
  608.                 {
  609.                     if(tei->tei_NoFilterMode ||
  610.                        NOT IS_CONTROL_CHARACTER(c) ||
  611.                        code == RAWKEY_BACKSPACE ||
  612.                        code == RAWKEY_TAB ||
  613.                        code == RAWKEY_ENTER ||
  614.                        code == RAWKEY_RETURN)
  615.                     {
  616.                         switch(c)
  617.                         {
  618.                             case '\b':
  619.  
  620.                                 if(code == RAWKEY_BACKSPACE)
  621.                                 {
  622.                                     if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  623.                                         TE_DeleteToStartOfLine(tec);
  624.                                     else
  625.                                         TE_RemoveChars(tec,1);
  626.                                 }
  627.                                 else
  628.                                 {
  629.                                     TE_AddString(tec,&c,1);
  630.                                 }
  631.  
  632.                                 break;
  633.  
  634.                             case '\t':
  635.  
  636.                                 if(code == RAWKEY_TAB)
  637.                                 {
  638.                                     (*gpi->gpi_Termination) = '\t';
  639.                 
  640.                                     result = GMR_VERIFY;
  641.                 
  642.                                     if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  643.                                         result |= GMR_NEXTACTIVE;
  644.                                     else
  645.                                         result |= GMR_PREVACTIVE;
  646.                                 }
  647.                                 else
  648.                                 {
  649.                                     TE_AddString(tec,&c,1);
  650.                                 }
  651.  
  652.                                 break;
  653.  
  654.                             case '\177':    /* del */
  655.  
  656.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  657.                                     TE_DeleteToEndOfLine(tec);
  658.                                 else
  659.                                     TE_DeleteChars(tec,1);
  660.  
  661.                                 break;
  662.  
  663.                             case '\r':
  664.  
  665.                                 if(code == RAWKEY_ENTER || code == RAWKEY_RETURN)
  666.                                 {
  667.                                     if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  668.                                     {
  669.                                         result = 0;
  670.                                         break;
  671.                                     }
  672.                                     else
  673.                                     {
  674.                                         c = '\n';
  675.                                     }
  676.                                 }
  677.  
  678.                                 /* FALLS THROUGH TO */
  679.  
  680.                             default:
  681.  
  682.                                 if(ToUpper(c) == 'X' && FLAG_IS_SET(qualifier,IEQUALIFIER_RCOMMAND))
  683.                                 {
  684.                                     TE_DeleteAll(tec);
  685.                                 }
  686.                                 else if (ToUpper(c) == 'Q' && FLAG_IS_SET(qualifier,IEQUALIFIER_RCOMMAND))
  687.                                 {
  688.                                     TE_RestoreBackup(tec);
  689.                                 }
  690.                                 else
  691.                                 {
  692.                                     TE_AddString(tec,&c,1);
  693.                                 }
  694.  
  695.                                 break;
  696.                         }
  697.                     }
  698.                     else if (IS_CONTROL_CHARACTER(c))
  699.                     {
  700.                         switch(c)
  701.                         {
  702.                             case '\001':    /* ^A */
  703.  
  704.                                 TE_CursorStartOfLine(tec);
  705.                                 break;
  706.  
  707.                             case '\b':
  708.  
  709.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  710.                                     TE_DeleteToStartOfLine(tec);
  711.                                 else
  712.                                     TE_RemoveChars(tec,1);
  713.  
  714.                                 break;
  715.  
  716.                             case '\013':    /* ^L */
  717.  
  718.                                 TE_DeleteToEndOfLine(tec);
  719.                                 break;
  720.  
  721.                             case '\025':    /* ^U */
  722.  
  723.                                 TE_DeleteToStartOfLine(tec);
  724.                                 break;
  725.  
  726.                             case '\027':    /* ^W */
  727.  
  728.                                 TE_RemoveWord(tec);
  729.                                 break;
  730.  
  731.                             case '\030':    /* ^X */
  732.  
  733.                                 TE_DeleteAll(tec);
  734.                                 break;
  735.  
  736.                             case '\032':    /* ^Z */
  737.  
  738.                                 TE_CursorEndOfLine(tec);
  739.                                 break;
  740.  
  741.                             case '\r':
  742.  
  743.                                 (*gpi->gpi_Termination) = 0;
  744.  
  745.                                 result = GMR_VERIFY;
  746.                                 break;
  747.                         }
  748.                     }
  749.                 }
  750.                 else
  751.                 {
  752.                     if((code >= CURSORUP && code <= CURSORLEFT) || (code == RAWKEY_HELP))
  753.                     {
  754.                         switch(code)
  755.                         {
  756.                             case CURSORUP:
  757.                 
  758.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  759.                                     TE_CursorPageUp(tec);
  760.                                 else if (FLAG_IS_SET(qualifier,IEQUALIFIER_ALT))
  761.                                     TE_CursorFirstLine(tec);
  762.                                 else
  763.                                     TE_CursorUp(tec,1);
  764.                 
  765.                                 break;
  766.                 
  767.                             case CURSORDOWN:
  768.                 
  769.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  770.                                     TE_CursorPageDown(tec);
  771.                                 else if (FLAG_IS_SET(qualifier,IEQUALIFIER_ALT))
  772.                                     TE_CursorLastLine(tec);
  773.                                 else
  774.                                     TE_CursorDown(tec,1);
  775.                 
  776.                                 break;
  777.                 
  778.                             case CURSORLEFT:
  779.                 
  780.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  781.                                     TE_CursorStartOfLine(tec);
  782.                                 else if (FLAG_IS_SET(qualifier,IEQUALIFIER_ALT))
  783.                                     TE_CursorStartOfLine(tec);
  784.                                 else
  785.                                     TE_CursorLeft(tec,1);
  786.                 
  787.                                 break;
  788.                 
  789.                             case CURSORRIGHT:
  790.                 
  791.                                 if(FLAG_IS_SET(qualifier,IEQUALIFIER_SHIFT))
  792.                                     TE_CursorEndOfLine(tec);
  793.                                 else if (FLAG_IS_SET(qualifier,IEQUALIFIER_ALT))
  794.                                     TE_CursorEndOfLine(tec);
  795.                                 else
  796.                                     TE_CursorRight(tec,1);
  797.                 
  798.                                 break;
  799.  
  800.                             case RAWKEY_HELP:
  801.  
  802.                                 if(tei->tei_ExitHelp)
  803.                                 {
  804.                                     (*gpi->gpi_Termination) = RAWKEY_HELP;
  805.  
  806.                                     result = GMR_VERIFY;
  807.                                 }
  808.  
  809.                                 break;
  810.                         }
  811.                     }
  812.                 }
  813.  
  814.                 ReleaseGIRPort(rp);
  815.  
  816.                 TE_SetTextEditRastPort(tec,NULL);
  817.             }
  818.         }
  819.     }
  820.  
  821.     if(TE_IsRedrawNecessary(tec))
  822.     {
  823.         struct RastPort * rp;
  824.  
  825.         rp = ObtainGIRPort(gpi->gpi_GInfo);
  826.         if(rp != NULL)
  827.         {
  828.             DoMethod(o,GM_RENDER,gpi->gpi_GInfo,rp,GREDRAW_UPDATE);
  829.  
  830.             ReleaseGIRPort(rp);
  831.         }
  832.     }
  833.  
  834.     return(result);
  835. }
  836.  
  837. STATIC VOID
  838. DisposeMethod(
  839.     Class *        cl,
  840.     Object *    o)
  841. {
  842.     struct TextEditInfo * tei = INST_DATA(cl,o);
  843.     struct TextEditContext * tec = tei->tei_Context;
  844.  
  845.     TE_DeleteTextEditContext(tec);
  846.     DisposeObject(tei->tei_Frame);
  847. }
  848.  
  849. /******************************************************************************/
  850.  
  851. ULONG SAVE_DS ASM
  852. LTP_TextEditClassDispatcher(
  853.     REG(a0) Class *        cl,
  854.     REG(a2) Object *    o,
  855.     REG(a1) Msg            msg)
  856. {
  857.     ULONG result;
  858.  
  859.     switch(msg->MethodID)
  860.     {
  861.         case OM_NEW:
  862.  
  863.             result = (ULONG)NewMethod(cl,o,(struct opSet *)msg);
  864.             break;
  865.  
  866.         case OM_SET:
  867.  
  868.             result = SetMethod(cl,o,(struct opSet *)msg);
  869.             break;
  870.  
  871.         case OM_GET:
  872.  
  873.             result = GetMethod(cl,o,(struct opGet *)msg);
  874.             break;
  875.  
  876.         case GM_RENDER:
  877.  
  878.             result = RenderMethod(cl,o,(struct gpRender *)msg);
  879.             break;
  880.  
  881.         case GM_HITTEST:
  882.  
  883.             result = HitTestMethod(cl,o,(struct gpHitTest *)msg);
  884.             break;
  885.  
  886.         case GM_GOINACTIVE:
  887.  
  888.             result = InactiveMethod(cl,o,(struct gpGoInactive *)msg);
  889.             break;
  890.  
  891.         case GM_GOACTIVE:
  892.  
  893.             result = ActiveMethod(cl,o,(struct gpInput *)msg);
  894.             break;
  895.  
  896.         case GM_HANDLEINPUT:
  897.  
  898.             result = InputMethod(cl,o,(struct gpInput *)msg);
  899.             break;
  900.  
  901.         case OM_DISPOSE:
  902.  
  903.             DisposeMethod(cl,o);
  904.  
  905.             /* FALLS THROUGH TO */
  906.  
  907.         default:
  908.  
  909.             result = DoSuperMethodA(cl,o,msg);
  910.             break;
  911.     }
  912.  
  913.     return(result);
  914. }
  915.  
  916. /******************************************************************************/
  917.  
  918. #endif /* DO_TEXTEDIT_KIND */
  919.